﻿using AntMovement.Core;
using AntMovement.Core.Attributes;
using AntMovement.Core.Entity;
using AntMovement.Core.Hardware;
using AntMovement.Core.IParameter;
using AntMovement.Core.Logic;
using AntMovement.Core.Logic.Base;
using AntMovement.Core.Model;
using AntMovement.Parameter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AntMovement.Tasks
{
    [FlowAttributes(nameof(AxisJogHome), 2)]
    public class AxisJogHome : TaskBase
    {
        #region 轴变量
        private AxisMotion _axis = default;
        #endregion

        #region 上升沿
        #endregion

        #region 定时器
        #endregion

        #region 点位
        #endregion

        #region 输入点
        #endregion

        #region 输出点
        #endregion

        #region 报警变量
        #endregion

        #region 私有变量
        private List<IAirCylinder> _airCylinders;
        private IList<AxisMotion> _axisAll;
        private string _fixedPointName = string.Empty;
        private long _fixedPointPulse = 0;
        #endregion
        public AxisJogHome(ITemporaryParameter temporary, IIOParameter iop, IAxisParameter axisp, IDialogHost dialogHost, ILog log)
            : base(temporary, iop, axisp, dialogHost, log)
        {
            _temporary.AxisHome = false;
            _airCylinders = iop.GetAirCylinderAll();
            _axisAll = _axisParameter.GetAxisAll();
        }

        public override void EmergencyStop()
        {
            foreach (var axisMotion in _axisAll)
            {
                axisMotion.Stop(1);
            }
        }

        public override void Handle()
        {
            if (_temporary.SystemStatus.Auto)
            {
            }
            if (_temporary.SystemStatus.ManualOperation && !_temporary.Monocycle)
            {
                #region Jog
                foreach (var item in _axisAll)
                {
                    item.Continuous(item.Text == _temporary.JogName && _temporary.JogUp, item.Text == _temporary.JogName && _temporary.JogDown);
                }
                #endregion
                #region 回原
                foreach (var item in _axisAll)
                {
                    if (_temporary.AxisHome && item.Text == _temporary.AxisNameHome)
                    {
                        item.Home();
                        _temporary.AxisHome = !item.HomeComplete;
                    }
                }
                #endregion
                #region 点动
                if (_temporary.FixedPointMove)
                {
                    if (_fixedPointName != _temporary.FixedPointName)
                    {
                        _log.Info($"[{_temporary.FixedPointName}] 定点: {_temporary.FixedPointDistance} mm");
                        _fixedPointName = _temporary.FixedPointName;
                        var entity = _axisParameter.GetAxisEntity(_fixedPointName);
                        _fixedPointPulse = DistanceToPulse(_temporary.FixedPointDistance, entity);
                        _axis = _axisParameter.GetAxisMotion(_fixedPointName);
                    }
                    if (_axis != null)
                    {
                        _axis.Move(_fixedPointPulse, 60000);
                        if (_axis.ArrivalLocation)
                        {
                            _temporary.FixedPointMove = false;
                            _fixedPointName = string.Empty;
                        }
                    }
                    else
                    {
                        _temporary.FixedPointMove = false;
                        _fixedPointName = default;
                    }
                }
                #endregion
                if (!string.IsNullOrEmpty(_temporary.ServoName))
                {
                    var axis = _axisParameter.GetAxisMotion(_temporary.ServoName);
                    if (axis != null)
                    {
                        axis.SetServo(_temporary.ServoEnable);
                        _temporary.ServoName = default;
                        _temporary.ServoEnable = false;
                    }
                }
            }
            foreach (var item in _airCylinders)
            {
                item.Execute(_temporary.SystemStatus.Auto, _temporary.SystemStatus.ManualOperation);
            }
            foreach (var item in _iop.GetSingleControlAll())
            {
                item.Execute(_temporary.SystemStatus.Auto, _temporary.SystemStatus.ManualOperation);
            }
            _temporary.SystemStatus.AlarmStop = (_axisAll.Any(x => x.AlarmHome || x.AlarmMove || x.Alm || x.EMG)) || _airCylinders.Any(x => x.Alarm) || _temporary.SystemStatus.AlarmStop;
        }

        #region 脉冲值转换
        private float PulseToDistance(long pulse, Axis axis) => (float)Math.Round(GetPE(axis) * (double)axis.Status.CurrentPostion, 6, MidpointRounding.AwayFromZero);

        private long DistanceToPulse(double distance, Axis axis) => (long)Math.Round(distance / GetPE(axis), 6, MidpointRounding.AwayFromZero);

        private double GetPE(Axis axis)
        {
            double pe = 0;
            if (axis.UnitConversion.EnableGearbox)
            {
                if (axis.UnitConversion.EnableRotationMode)
                {
                    //旋转模式

                }
                else
                {
                    //线性模式
                    pe = (axis.UnitConversion.WeeklyItinerary * axis.UnitConversion.MotorGearRatio) / (axis.UnitConversion.CyclePulse * axis.UnitConversion.WorkingGearRatio);
                }
            }
            else
            {
                pe = axis.UnitConversion.WeeklyItinerary / axis.UnitConversion.CyclePulse;
            }
            return pe;
        }
        #endregion

        public override void Resetting()
        {
            _log.ResettingError();
            if (!_temporary.SystemStatus.Auto)
            { 
                foreach (var axisMotion in _axisAll)
                {
                    axisMotion.Resetting();
                }            
            }
            foreach (var item in _airCylinders)
            {
                item.Resetting();
            }
            _temporary.JogUp = false; 
            _temporary.JogDown = false;
            _temporary.AxisHome = false;
            _temporary.FixedPointMove = false;
            _fixedPointName = string.Empty;
        }

        public override void SafeStop()
        {
            foreach (var axisMotion in _axisAll)
            {
                axisMotion.Stop(1);
            }
        }
    }
}
